package org.ihelpuoo.weboo.security;

import java.util.Enumeration;
import java.util.Locale;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.PageContext;

import org.ihelpuoo.algorithm.random.GM;

// @ TODO ZZH: think about the SessionListener.
public class SessionImpl implements Session
{

	private static final String	LOCALE_NAME			= Session.class.getName() + ".locale";
	private static final String	VERIFY_CODE_NAME	= Session.class.getName() + ".verify_code";

	public static Session wrap(HttpServletRequest request)
	{
		return new SessionImpl(request.getSession());
	}

	public static Session wrap(PageContext pc)
	{
		return new SessionImpl(pc.getSession());
	}

	private SessionImpl(HttpSession session)
	{
		this.session = session;
	}

	private HttpSession	session;

	public Object getAttribute(String name)
	{
		return session.getAttribute(name);
	}

	public Enumeration getAttributeNames()
	{
		return session.getAttributeNames();
	}

	public long getCreationTime()
	{
		return session.getCreationTime();
	}

	public String getId()
	{
		return session.getId();
	}

	public long getLastAccessedTime()
	{
		return session.getLastAccessedTime();
	}

	public int getMaxInactiveInterval()
	{
		return session.getMaxInactiveInterval();
	}

	public ServletContext getServletContext()
	{
		return session.getServletContext();
	}

	public void invalidate()
	{
		session.invalidate();
	}

	public boolean isNew()
	{
		return session.isNew();
	}

	public void removeAttribute(String name)
	{
		session.removeAttribute(name);
	}

	public synchronized void setAttribute(String name, Object value)
	{
		session.setAttribute(name,value);
	}

	public synchronized void setMaxInactiveInterval(int v)
	{
		session.setMaxInactiveInterval(v);
	}

	public Account getAccount()
	{
		return (Account)getAttribute(Account.class.getName());
	}

	public boolean isLogined()
	{
		return null != getAccount();
	}

	public synchronized void setAccount(Account account)
	{
		setAttribute(Account.class.getName(),account);
	}

	public void logout()
	{
		Account a = getAccount();
		if (null != a)
		{
			session.removeAttribute(Account.class.getName());
		}
	}

	public Locale getLocale()
	{
		return (Locale)this.session.getAttribute(LOCALE_NAME);
	}

	public synchronized void setLocale(Locale locale)
	{
		session.setAttribute(LOCALE_NAME,locale);
	}

	public char[] refreshVerifyCode(int size)
	{
		char[] re = new char[size];
		for (int i = 0; i < size; i++)
			re[i] = Security.CODES[GM.gRandom(0,Security.CODES.length - 1)];
		session.setAttribute(VERIFY_CODE_NAME,re);
		return re;
	}

	public char[] getVerifyCode()
	{
		return (char[])session.getAttribute(VERIFY_CODE_NAME);
	}

	public boolean verifyCode(String cs)
	{
		if (null == cs)
			return false;
		char[] vc = getVerifyCode();
		if (null == vc)
			return false;
		if (cs.length() != vc.length)
			return false;
		char[] codes = cs.toUpperCase().toCharArray();
		for (int i = 0; i < codes.length; i++)
			if (codes[i] != vc[i])
				return false;
		return true;
	}

}
